package cn.minhx.infrastructure.adapter.repository;

import cn.minhx.domain.activity.model.valobj.ActivityStatusEnumVO;
import cn.minhx.domain.trade.adapter.repostitory.ITradeRepository;
import cn.minhx.domain.trade.moedel.aggregate.GroupBuyOrderAggregate;
import cn.minhx.domain.trade.moedel.aggregate.GroupBuyTeamSettlementAggregate;
import cn.minhx.domain.trade.moedel.entity.*;
import cn.minhx.domain.trade.moedel.valobj.GroupBuyOrderEnumVO;
import cn.minhx.domain.trade.moedel.valobj.GroupBuyProgressVO;
import cn.minhx.domain.trade.moedel.valobj.TradeOrderStatusEnumVO;
import cn.minhx.infrastructure.dao.IGroupBuyActivityDAO;
import cn.minhx.infrastructure.dao.IGroupBuyOrderDAO;
import cn.minhx.infrastructure.dao.IGroupBuyOrderItemDAO;
import cn.minhx.infrastructure.dao.INotifyTaskDAO;
import cn.minhx.infrastructure.dao.po.GroupBuyActivity;
import cn.minhx.infrastructure.dao.po.GroupBuyOrder;
import cn.minhx.infrastructure.dao.po.GroupBuyOrderItem;
import cn.minhx.infrastructure.dao.po.NotifyTask;
import cn.minhx.infrastructure.dcc.DCCService;
import cn.minhx.types.enums.ResponseCode;
import cn.minhx.types.exception.AppException;
import com.alibaba.fastjson2.JSON;
import jakarta.annotation.Resource;
import java.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 * 交易仓储服务
 *
 * @author min
 */
@Slf4j
@Repository
public class TradeRepository implements ITradeRepository {

	@Resource
	private IGroupBuyOrderDAO groupBuyOrderDAO;
	@Resource
	private IGroupBuyOrderItemDAO groupBuyOrderItemDAO;
	@Resource
	private IGroupBuyActivityDAO groupBuyActivityDAO;
	@Resource
	private INotifyTaskDAO notifyTaskDAO;
	@Resource
	private DCCService dccService;
	@Override
	public MarketPayOrderEntity queryMarketPayOrderEntityByOutTradeNo(String userId, String outTradeNo) {
		GroupBuyOrderItem groupBuyOrderItemReq = new GroupBuyOrderItem();
		groupBuyOrderItemReq.setUserId(userId);
		groupBuyOrderItemReq.setOutTradeNo(outTradeNo);
		GroupBuyOrderItem groupBuyOrderItemRes = groupBuyOrderItemDAO
				.queryGroupBuyOrderRecordByOutTradeNo(groupBuyOrderItemReq);
		if (null == groupBuyOrderItemRes) {
			return null;
		}
		return MarketPayOrderEntity.builder().teamId(groupBuyOrderItemRes.getTeamId())
				.orderId(groupBuyOrderItemRes.getOrderId()).discountedPrice(groupBuyOrderItemRes.getDiscountedPrice())
				.tradeOrderStatusEnumVO(TradeOrderStatusEnumVO.valueOf(groupBuyOrderItemRes.getStatus())).build();
	}

	@Override
	public GroupBuyProgressVO queryGroupBuyProgress(String teamId) {
		GroupBuyOrder groupBuyOrder = groupBuyOrderDAO.queryGroupBuyProgress(teamId);
		if (null == groupBuyOrder) {
			return null;
		}
		return GroupBuyProgressVO.builder().completeCount(groupBuyOrder.getCompleteCount())
				.targetCount(groupBuyOrder.getTargetCount()).lockCount(groupBuyOrder.getLockCount()).build();
	}

	@Override
	public MarketPayOrderEntity lockMarketPayOrder(GroupBuyOrderAggregate groupBuyOrderAggregate) {
		UserEntity userEntity = groupBuyOrderAggregate.getUserEntity();
		PayActivityEntity payActivityEntity = groupBuyOrderAggregate.getPayActivityEntity();
		PayDiscountEntity payDiscountEntity = groupBuyOrderAggregate.getPayDiscountEntity();
		// 拼团单
		String teamId = payActivityEntity.getTeamId();
		if (StringUtils.isBlank(teamId)) {
			// todo teamId
			teamId = UUID.randomUUID().toString().replaceAll("-", "");
			// 构建拼团订单
			GroupBuyOrder groupBuyOrder = GroupBuyOrder.builder().teamId(teamId)
					.activityId(payActivityEntity.getActivityId()).source(payDiscountEntity.getSource())
					.channel(payDiscountEntity.getChannel()).originalPrice(payDiscountEntity.getOriginalPrice())
					.discountedPrice(payDiscountEntity.getDiscountedPrice())
					.payPrice(payDiscountEntity.getDiscountedPrice()).targetCount(payActivityEntity.getTargetCount())
					.notifyUrl(payDiscountEntity.getNotifyUrl()).completeCount(0).lockCount(1).build();
			// 写入
			groupBuyOrderDAO.insert(groupBuyOrder);
		} else {
			// 更新记录 - 如果更新记录不等于1，则表示拼团已满，抛出异常
			int updateAddTargetCount = groupBuyOrderDAO.updateAddLockCount(teamId);
			if (1 != updateAddTargetCount) {
				throw new AppException(ResponseCode.E0005);
			}
		}
		// 生成拼团子订单
		// todo orderId
		String orderId = RandomStringUtils.randomNumeric(12);
		GroupBuyOrderItem groupBuyOrderItem = GroupBuyOrderItem.builder().userId(userEntity.getUserId()).teamId(teamId)
				.orderId(orderId).activityId(payActivityEntity.getActivityId())
				.startTime(payActivityEntity.getStartTime()).endTime(payActivityEntity.getEndTime())
				.goodsId(payDiscountEntity.getGoodsId()).source(payDiscountEntity.getSource())
				.channel(payDiscountEntity.getChannel()).originalPrice(payDiscountEntity.getOriginalPrice())
				.discountedPrice(payDiscountEntity.getDiscountedPrice()).status(TradeOrderStatusEnumVO.CREATE.getCode())
				.outTradeNo(payDiscountEntity.getOutTradeNo()).build();
		try {
			// 写入拼团子订单
			groupBuyOrderItemDAO.insert(groupBuyOrderItem);
		} catch (DuplicateKeyException e) {
			throw new AppException(ResponseCode.DUPLICATE_KEY_EXCEPTION);
		}
		return MarketPayOrderEntity.builder().orderId(orderId).discountedPrice(payDiscountEntity.getDiscountedPrice())
				.tradeOrderStatusEnumVO(TradeOrderStatusEnumVO.CREATE).build();
	}

	@Override
	public GroupBuyActivityEntity queryGroupBuyActivityEntityByActivityId(Long activityId) {
		GroupBuyActivity groupBuyActivity = groupBuyActivityDAO.queryGroupBuyActivityByActivityId(activityId);
		return GroupBuyActivityEntity.builder().activityId(groupBuyActivity.getActivityId())
				.activityName(groupBuyActivity.getActivityName()).discountId(groupBuyActivity.getDiscountId())
				.groupType(groupBuyActivity.getGroupType()).takeLimitCount(groupBuyActivity.getTakeLimitCount())
				.target(groupBuyActivity.getTarget()).validTime(groupBuyActivity.getValidTime())
				.status(ActivityStatusEnumVO.valueOf(groupBuyActivity.getStatus()))
				.startTime(groupBuyActivity.getStartTime()).endTime(groupBuyActivity.getEndTime())
				.tagId(groupBuyActivity.getTagId()).tagScope(groupBuyActivity.getTagScope()).build();
	}

	@Override
	public Integer queryOrderCountByActivityId(Long activityId, String userId) {
		GroupBuyOrderItem groupBuyOrderItemReq = new GroupBuyOrderItem();
		groupBuyOrderItemReq.setActivityId(activityId);
		groupBuyOrderItemReq.setUserId(userId);
		return groupBuyOrderItemDAO.queryOrderCountByActivityId(groupBuyOrderItemReq);
	}

	@Override
	public GroupBuyTeamEntity queryGroupBuyTeamByTeamId(String teamId) {
		GroupBuyOrder groupBuyOrder = groupBuyOrderDAO.queryGroupBuyTeamByTeamId(teamId);
		return GroupBuyTeamEntity.builder().teamId(groupBuyOrder.getTeamId()).activityId(groupBuyOrder.getActivityId())
				.targetCount(groupBuyOrder.getTargetCount()).completeCount(groupBuyOrder.getCompleteCount())
				.lockCount(groupBuyOrder.getLockCount()).status(GroupBuyOrderEnumVO.valueOf(groupBuyOrder.getStatus()))
				.build();
	}

	@Override
	@Transactional(timeout = 500, rollbackFor = Exception.class)
	public boolean settlementMarketPayOrder(GroupBuyTeamSettlementAggregate groupBuyTeamSettlementAggregate) {
		UserEntity userEntity = groupBuyTeamSettlementAggregate.getUserEntity();
		GroupBuyTeamEntity groupBuyTeamEntity = groupBuyTeamSettlementAggregate.getGroupBuyTeamEntity();
		TradePaySuccessEntity tradePaySuccessEntity = groupBuyTeamSettlementAggregate.getTradePaySuccessEntity();
		// 1. 更新拼团订单明细状态
		GroupBuyOrderItem groupBuyOrderItemReq = new GroupBuyOrderItem();
		groupBuyOrderItemReq.setUserId(userEntity.getUserId());
		groupBuyOrderItemReq.setOutTradeNo(tradePaySuccessEntity.getOutTradeNo());
		int updateOrderListStatusCount = groupBuyOrderItemDAO.updateOrderItemStatusToComplete(groupBuyOrderItemReq);
		if (1 != updateOrderListStatusCount) {
			throw new AppException(ResponseCode.UPDATE_ZERO);
		}
		// 2. 更新拼团达成数量(+1)
		int updateAddCount = groupBuyOrderDAO.incrementCompleteCount(groupBuyTeamEntity.getTeamId());
		if (1 != updateAddCount) {
			throw new AppException(ResponseCode.UPDATE_ZERO);
		}
		// 3. 更新拼团完成状态
		if (groupBuyTeamEntity.getTargetCount() - groupBuyTeamEntity.getCompleteCount() == 1) {
			int updateOrderStatusCount = groupBuyOrderDAO.updateOrderStatusToComplete(groupBuyTeamEntity.getTeamId());
			if (1 != updateOrderStatusCount) {
				throw new AppException(ResponseCode.UPDATE_ZERO);
			}

			// 查询拼团交易完成外部单号列表
			List<String> outTradeNoList = groupBuyOrderItemDAO
					.queryGroupBuyCompleteOrderOutTradeNoListByTeamId(groupBuyTeamEntity.getTeamId());

			// 拼团完成写入回调任务记录
			Map<String, Object> parameters = Map.of("teamId", groupBuyTeamEntity.getTeamId(), "outTradeNoList",
					outTradeNoList);
			NotifyTask notifyTask = NotifyTask.builder().activityId(groupBuyTeamEntity.getActivityId())
					.teamId(groupBuyTeamEntity.getTeamId()).notifyUrl("暂无").notifyCount(0).notifyStatus(0)
					.parameterJson(JSON.toJSONString(parameters)).build();
			notifyTaskDAO.insert(notifyTask);
			return true;
		}
		return false;
	}

	@Override
	public boolean isSCBlackIntercept(String source, String channel) {
		return dccService.isSCBlackIntercept(source, channel);
	}

	@Override
	public List<NotifyTaskEntity> queryUnExecutedNotifyTaskList() {
		List<NotifyTask> notifyTaskList = notifyTaskDAO.queryUnExecutedNotifyTaskList();
		if (notifyTaskList.isEmpty())
			return new ArrayList<>();

		List<NotifyTaskEntity> notifyTaskEntities = new ArrayList<>();
		for (NotifyTask notifyTask : notifyTaskList) {

			NotifyTaskEntity notifyTaskEntity = NotifyTaskEntity.builder().teamId(notifyTask.getTeamId())
					.notifyUrl(notifyTask.getNotifyUrl()).notifyCount(notifyTask.getNotifyCount())
					.parameterJson(notifyTask.getParameterJson()).build();

			notifyTaskEntities.add(notifyTaskEntity);
		}

		return notifyTaskEntities;
	}

	@Override
	public List<NotifyTaskEntity> queryUnExecutedNotifyTaskList(String teamId) {
		NotifyTask notifyTask = notifyTaskDAO.queryUnExecutedNotifyTaskByTeamId(teamId);
		if (null == notifyTask)
			return new ArrayList<>();
		return Collections.singletonList(
				NotifyTaskEntity.builder().teamId(notifyTask.getTeamId()).notifyUrl(notifyTask.getNotifyUrl())
						.notifyCount(notifyTask.getNotifyCount()).parameterJson(notifyTask.getParameterJson()).build());
	}

	@Override
	public int updateNotifyTaskStatusSuccess(String teamId) {
		return notifyTaskDAO.updateNotifyTaskStatusSuccess(teamId);
	}

	@Override
	public int updateNotifyTaskStatusError(String teamId) {
		return notifyTaskDAO.updateNotifyTaskStatusError(teamId);
	}

	@Override
	public int updateNotifyTaskStatusRetry(String teamId) {
		return notifyTaskDAO.updateNotifyTaskStatusRetry(teamId);
	}
}
